home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / cobalts.zip / COBALTS.C < prev    next >
Text File  |  1990-09-03  |  17KB  |  523 lines

  1.  
  2. /* Mix Power C 2.0 Large Memory Model */
  3.  
  4. /* uncomment the next line to use with MICROSOFT */
  5. /* #define MICROSOFT */
  6.  
  7. /* this program uses a CGA emulation routine for the HERC to allow */
  8. /* HERCULES Graphics card users to view CGA compatible graphics.   */
  9.  
  10.  
  11.     /* =================[ CGA to HERCULES conversion ]===============*/
  12.  
  13.     /* Comparison Ratio:          pixels    size                     */
  14.     /* the hercules display is    720 =  90 bytes wide               */
  15.     /*                            348 =  87 "half-bytes" deep        */
  16.     /* the cga HI_RES display is  640 =  80 bytes wide               */
  17.     /*                            200 =  50 "half-bytes" deep        */
  18.     /* horizontal transformation reduction 8:9 =                     */
  19.     /*                            640 =  80 bytes literal            */
  20.     /* vertical transformation ratio       3:2 =                     */
  21.     /*                            300 =  50 "half-bytes" deep        */
  22.     /* A slightly (11%) smaller but reasonably accurate facsimile    */
  23.     /* of bit images ported from the cga may be displayed on the herc*/
  24.     /* by applying the horizontal resolution transformation factor   */
  25.     /* vertically then writing an extra scanline on every odd line   */
  26.     /* relative to CGA coordinates. This is done as a "filler" and   */
  27.     /* will widen horizontal lines in lineart reproductions if they  */
  28.     /* fall on the (interleaf) filler line. Also, the aspect ratio   */
  29.     /* is minimally (4%) reduced in the yaxis.                       */
  30.  
  31.     /* there are 2-significant advantages to this algorithm.         */
  32.     /* 1. speed of execution due to integer arithmetic and the use   */
  33.     /*    of the modulus operator and simple logic.                  */
  34.     /* 2. greater image clarity due to maintaining true pixel ratio  */
  35.     /*    in the x axis and a single-interleaf repeat in the y axis  */
  36.     /*    thereby preserving a regular transformation matrix ratio.  */
  37.  
  38.     /*===============================================================*/
  39.  
  40.  
  41. /* Made in Canada by bill buckels 1990
  42.  
  43.    a demonstration of embedded graphics and a virtual screen.
  44.  
  45.    1. we use all our own routines. These are not from a text book,
  46.       nor from someone's handy toolkit.
  47.  
  48.    2. Anyone wishing to use these routines to produce binary code may
  49.       do so without fee or royalty (although I would not return a
  50.       registration fee if received) and I would appreciate that no fee
  51.       be charged if you give these to another software engineer.
  52.  
  53.  
  54. */
  55.  
  56.  
  57. #include <stdio.h>
  58. #include <fcntl.h>
  59. #include <conio.h>
  60. #include <stdlib.h>
  61. #include <io.h>
  62. #include <dos.h>
  63. #include <bios.h>
  64. #include <string.h>
  65. #include <malloc.h>
  66.  
  67.  
  68. #ifdef MICROSOFT
  69. #define biosequip _bios_equiplist
  70. #define MK_FP(seg,off) ((char far *)(((long)(seg) << 16) | (off)))
  71. #endif
  72.  
  73. /* palettes */
  74. #define GRY     0
  75. #define CMW     1
  76.  
  77. /* screen modes */
  78. #define TEXT     3
  79. #define MED_RES  4
  80. #define HI_RES   6
  81. #define HERCULES 99
  82.  
  83. /* default adapter */
  84. int ADAPTER=MED_RES;
  85.  
  86. #define   FRAMEBUFFER 0xb800
  87. #define   HERCTEXT  0
  88. #define   HERCGRAPH 1
  89. int       HERCLEAF[4]={0x0000,0x2000,0x4000,0x6000};
  90. int       CGALEAF[2]={0,8192};
  91. #define   HERCLINE   90
  92. #define   CGALINE    80
  93.  
  94. /* we declare the screen buffer globally and allocate the memory */
  95. /* during initialization.*/
  96.  
  97. char far *crt;
  98.  
  99. /* The Image Descriptor Integer Array precedes the Character Array.*/
  100. /* Descriptor Fields are: 1.    Length of Character Array. */
  101. /*                        2.    Width of Graphic in BYTES. */
  102. /*                        3.    Height of Graphic in BYTES.*/
  103.  
  104. extern long int RUSS_SIZE[3];
  105. extern unsigned char far RUSS[];
  106.  
  107. /* we declare the screen buffer globally and allocate the memory */
  108. /* during initialization.*/
  109.  
  110. unsigned char far *screenbuffer[2];
  111. long screenlength;
  112. long screensize;
  113. long screenwidth;
  114.  
  115. void FREE_BUFF(void)
  116. {
  117.     _ffree(screenbuffer[0]);
  118.     _ffree(screenbuffer[1]);
  119. }
  120.  
  121. long int topline=0l;
  122. long int sideline=0l;
  123. /* this is the pointer to the beginning of the screenbuffer */
  124. long int topstop;
  125.  
  126. #define VIEWPORT 200
  127.  
  128. int STUFF_BUFF()
  129. {
  130.     screenlength= RUSS_SIZE[2];
  131.     screenwidth=  RUSS_SIZE[1];
  132.  
  133.     /* break point for the 64k buffer tanks */
  134.     /* break on even boundaries */
  135.     screensize=   (64000l/screenwidth)*screenwidth;
  136.  
  137.     topstop = screenlength-VIEWPORT;
  138.     /* arbitary mallocation of a large block */
  139.  
  140.  
  141.     screenbuffer[0] = _fmalloc(64000l);
  142.     screenbuffer[1] = _fmalloc(64000l);
  143.  
  144.     memset(screenbuffer[0],0x00,64000l);
  145.     memset(screenbuffer[1],0x00,64000l);
  146.  
  147.     crt=MK_FP(FRAMEBUFFER,0x0000);
  148.     return 0;
  149. }
  150.  
  151.  
  152.  
  153. int memoryload()
  154. {
  155.  
  156.     unsigned int packet;
  157.     unsigned char byte,bytecount;
  158.     long int wordcount=0, target=RUSS_SIZE[0],byteoff=0l;
  159.  
  160.  
  161.     do{ bytecount=1;                          /* start with a seed count */
  162.         byte=RUSS[wordcount];
  163.         wordcount++;
  164.                                               /* check to see if its raw */
  165.         if(0xC0 == (0xC0 &byte)){             /* if its not, run encoded */
  166.                     bytecount= 0x3f &byte;
  167.                     byte=RUSS[wordcount];
  168.                     wordcount++;
  169.                     }
  170.         for(packet=0;packet<bytecount;packet++){
  171.               if(byteoff<screensize)screenbuffer[0][byteoff]=byte;
  172.               else screenbuffer[1][byteoff-screensize]=byte;
  173.               byteoff++;
  174.               }
  175.         }while(wordcount<target);
  176.         return(0);
  177. }
  178.  
  179. void HERC_CLS(void)
  180. {
  181.   memset(crt,0,32767);
  182. }
  183.  
  184. /* 6485 controller mode data */
  185. char HERC_DAT[2][12] = { { 0x61, 0x50, 0x52, 0x0f, 0x19, 0x06,
  186.                          0x19, 0x19, 0x02, 0x0d, 0x0b, 0x0c  },
  187.                        { 0x35, 0x2d, 0x2e, 0x07, 0x5b, 0x02,
  188.                          0x57, 0x57, 0x02, 0x03, 0x00 ,0x00  } };
  189. void HERC_MODE(int ctrlmode)
  190. {
  191.    unsigned int reg,ctrl;
  192.    ctrl = (ctrlmode) ? 0x82 : 0x20;
  193.    outp(0x3bf,3)                  ;  /* allow graphics enable page 1 */
  194.    outp(0x3b8,ctrl)               ;  /* disable video and set mode   */
  195.    for (reg = 0; reg <= 11; reg++) { /* program the crt parameters   */
  196.         outp(0x3b4,reg)           ;
  197.         outp(0x3b5,HERC_DAT[ctrlmode][reg]);
  198.         }
  199.    outp(0x3b8,ctrl+8)             ;  /* re-enable the video          */
  200. }
  201.  
  202. int setcrtmode(unsigned char _CRT_MODE)
  203. {
  204.     union REGS rin,rout;
  205.  
  206.     if ((biosequip() & 0x30) == 0x30){
  207.         ADAPTER=HERCULES                ;
  208.         if(_CRT_MODE == TEXT){
  209.                 HERC_CLS()              ;
  210.                 HERC_MODE(HERCTEXT)     ;
  211.                 }
  212.            else{HERC_MODE(HERCGRAPH)    ;
  213.                 HERC_CLS()              ;
  214.                 }
  215.             return (0)                  ;
  216.             }
  217.  
  218.     rin.h.ah = 0;
  219.     rin.h.al = _CRT_MODE;
  220.     int86(0x10,&rin,&rout);
  221.     return 0;
  222.  
  223. }
  224.  
  225. int colorset(background, palette)
  226. unsigned char background, palette;
  227. {
  228.     union REGS rin,rout;
  229.     
  230.     if(ADAPTER==HERCULES || ADAPTER==HI_RES) return 0;
  231.     rin.h.ah = 11;
  232.     rin.h.bh = 0;
  233.     rin.h.bl = background;
  234.     int86(0x10,&rin,&rout);
  235.     rin.h.bh = 1;
  236.     rin.h.bl = palette;
  237.     int86(0x10,&rin,&rout);
  238.     return 0;
  239. }
  240.  
  241.  
  242. int cload()
  243. {
  244.   unsigned int y,inset=((HERCLINE*6)+5);
  245.   long offset=(topline*screenwidth)+sideline;
  246.  
  247.  
  248.  if(ADAPTER==HERCULES){
  249.     for(y=0;y!=300;y++){
  250.         if(offset<screensize)
  251.      memcpy((crt+HERCLEAF[y%4]+inset),(screenbuffer[0]+offset),CGALINE);
  252.         else
  253.      memcpy((crt+HERCLEAF[y%4]+inset),(screenbuffer[1]+(offset-screensize)),
  254.              CGALINE);
  255.         if(y%4==3)inset+=HERCLINE;
  256.         if(y%3!=2)offset+=screenwidth;
  257.         }
  258.     return(0);
  259.     }
  260.  
  261.     inset = 0;
  262.  
  263.     for(y=0;y<200;){
  264.  
  265.     if(offset<screensize)
  266.     memcpy((crt+CGALEAF[0]+inset),(screenbuffer[0]+offset),CGALINE);
  267.     else
  268.     memcpy((crt+CGALEAF[0]+inset),(screenbuffer[1]+(offset-screensize)),
  269.     CGALINE);
  270.  
  271.     offset+=screenwidth;y++;
  272.  
  273.     if(offset<screensize)
  274.     memcpy((crt+CGALEAF[1]+inset),(screenbuffer[0]+offset),CGALINE);
  275.     else
  276.     memcpy((crt+CGALEAF[1]+inset),(screenbuffer[1]+(offset-screensize)),
  277.     CGALINE);
  278.                    offset+=screenwidth;
  279.                    inset+=CGALINE;
  280.                    y++;
  281.                    }
  282.      return(0);
  283.  
  284. }
  285.  
  286.  
  287. #define ESCKEY     '\x1b' /* character generated by the Esc key            */
  288. #define FUNCKEY    '\x00' /* first character generated by function keys    */
  289. #define HOMEKEY    'G'    /* second character generated by Home key        */
  290. #define ENDKEY     'O'    /* second character generated by End key         */
  291. #define UPARROW    'H'    /* second character generated by up-arrow key    */
  292. #define DOWNARROW  'P'    /* second character generated by down-arrow key  */
  293. #define LEFTARROW  'K'    /* second character generated by left-arrow key  */
  294. #define RIGHTARROW 'M'    /* second character generated by right-arrow key */
  295. #define PGUP       'I'    /* second character generated by page up key     */
  296. #define PGDOWN     'Q'    /* second character generated by page down key   */
  297.  
  298.  
  299. /* colors */
  300. #define BLACK   0
  301. #define BLUE    1
  302. #define GREEN   2
  303. #define CYAN    3
  304. #define RED     4
  305. #define MAGENTA 5
  306. #define BROWN   6
  307. #define WHITE   7
  308. #define BWHITE  15
  309. #define BBLUE   9
  310.  
  311. #define INTENSE 16
  312.  
  313. /* Mix provide a sound function with their library */
  314. /* as do turbo but Microsoft (& Aztec) don't.      */
  315.  
  316. #define TIMEOUT 0x2c00
  317.  
  318. int sounds(freq,tlen)
  319. int freq;         /* freq of sound in Hertz                  */
  320. int tlen;         /* duration of sound 18.2 ticks per second */
  321. {
  322.     union REGS inregs,outregs;
  323.     unsigned frdiv = 1331000L/freq;   /* timer divisor */
  324.     int seed,hiseed,hold=0,setting;
  325.       
  326.     outp(0x43,0xB6) ;            /* write timer mode register */
  327.     outp(0x42,frdiv & 0x00FF);  /* write divisor LSB */
  328.     outp(0x42,frdiv >> 8);      /* write divisor MSB */
  329.  
  330.     setting= inp(0x61);          /* get current port B setting */
  331.     outp(0x61,setting | 0x03);   /* turn speaker on */
  332.  
  333.     if(tlen>0){
  334.        tlen=((tlen*1000)/182); /* convert from 18.2 ticks to 100ths */
  335.        inregs.x.ax= TIMEOUT;
  336.        int86(0x21,&inregs,&outregs);
  337.        seed=(outregs.x.dx)&0xff;
  338.  
  339.     while(hold<tlen)
  340.      {
  341.        inregs.x.ax = TIMEOUT;
  342.        int86(0x21,&inregs,&outregs);
  343.        if(seed!=(outregs.x.dx&0xff))
  344.         {
  345.           hiseed= (outregs.x.dx)&0xff;
  346.           if(hiseed<seed)hiseed+=100;
  347.           hold+=(hiseed-seed);
  348.           seed =(outregs.x.dx)&0xff;
  349.           }
  350.           }
  351.           }
  352.  
  353.     outp(0x61,setting);
  354.     /* restore port B setting */
  355.     return;
  356. }
  357.  
  358.  
  359. extern int ENTRTAN[];
  360. /* musical array created from file ENTRTAN.SND */
  361. /* array structure is frequency,duration */
  362.  
  363. int enterfreq=0, enterdur=1;
  364. char entertain()
  365. {
  366.   while(!kbhit())
  367.      {
  368.       sounds(ENTRTAN[enterfreq],ENTRTAN[enterdur]);
  369.       enterfreq+=2 ; enterdur+=2;
  370.       if (ENTRTAN[enterfreq] == -1)return 27;
  371.       }
  372.       return 0;
  373.  
  374. }
  375.  
  376.  
  377.  
  378. char *lineby[]={
  379.            "┌─────────────────────────────────────────────┐",
  380.            "│ Compliments of Teacher's Choice Productions │",
  381.            "│     written and produced by Bill Buckels    │",
  382.            "│                                             │",
  383.            "│       Hotkeys are The Cursor Arrows         │",
  384.            "│      Page Up and Down , Home and End        │",
  385.            "│        Press \"C\" to Toggle Palettes         │",
  386.            "│                                             │",
  387.            "│        Press Escape To Exit When Done       │",
  388.            "└─────────────────────────────────────────────┘",
  389.            "",
  390.            "One Moment Please...",
  391.            NULL};
  392.  
  393.  
  394.  
  395. main()
  396. {
  397.        char c=32;
  398.        int i=0;
  399.        int background=BLUE ;
  400.        int palette   =CMW  ;
  401.        long int temp;
  402.  
  403.  
  404.        while(strcmpi(lineby[i],NULL)!=0){printf("%s\n",lineby[i]);i++;}
  405.  
  406.        STUFF_BUFF();
  407.        /* load the buffer */
  408.        memoryload();
  409.        setcrtmode(ADAPTER);  /* initialize video */
  410.  
  411.        colorset(background,palette);
  412.  
  413.        /* load into the middle of the screen */
  414.  
  415.        temp=(screenlength-200l)/2;
  416.        if(temp>0)topline=temp;
  417.        temp=(screenwidth-80l)/2;
  418.        if(temp>0)sideline=temp;
  419.  
  420.        cload();
  421.  
  422.        /* loop until an escape key is pressed */
  423.        while(c!=ESCKEY)
  424.        {
  425.               if(kbhit())c=getch();
  426.               else if(entertain()==ESCKEY)c=ESCKEY;
  427.  
  428.               if(c!=ESCKEY)
  429.               {
  430.  
  431.                  /* color change option */
  432.                  if(c=='c'|| c=='C'){
  433.                                           palette++;
  434.                                           if(palette>CMW){
  435.                                              background++;
  436.                                              palette=GRY ;
  437.                                              if(background>31)
  438.                                                 background=BLACK;
  439.                                             }
  440.                                           colorset(background,palette);
  441.                                           }
  442.                  if(c==FUNCKEY){   /* if its a function key */
  443.                     c=getch();     /* get second character. */
  444.                          switch(c)
  445.                             {
  446.                                 case UPARROW:
  447.  
  448.                                           if(topline<1)break;
  449.                                           if(topline>0)topline-=2;
  450.                                           else topline=0;
  451.                                           cload();
  452.                                           break;
  453.  
  454.                                 case DOWNARROW:
  455.  
  456.                                           if(topline==topstop)break;
  457.                                           if(topline<topstop)topline+=2;
  458.                                           else topline=topstop;
  459.                                           cload();
  460.                                           break;
  461.  
  462.                                case PGUP:
  463.                                           if(topline<1)break;
  464.                                           if(topline>199)topline-=200;
  465.                                           else topline=0;
  466.                                           memset(crt,0x00,0x4000);
  467.                                           cload();
  468.                                           break;
  469.  
  470.                                case PGDOWN:
  471.                                           if(topline==topstop)break;
  472.                                           topline+=200;
  473.                                           if(topline>topstop)topline=topstop;
  474.                                           memset(crt,0x00,0x4000);
  475.                                           cload();
  476.                                           break;
  477.  
  478.  
  479.                                 case HOMEKEY:
  480.                                           if(topline<1)break;
  481.                                           topline=0;
  482.                                           memset(crt,0x00,0x4000);
  483.                                           cload();
  484.                                           break;
  485.  
  486.                                 case ENDKEY:
  487.                                           if(topline==topstop)break;
  488.                                           topline=topstop;
  489.                                           memset(crt,0x00,0x4000);
  490.                                           cload();
  491.                                           break;
  492.  
  493.                                 case LEFTARROW:
  494.                                          if(sideline<1)break;
  495.                                          sideline--;
  496.                                          cload();
  497.                                          break;
  498.  
  499.                                 case RIGHTARROW:
  500.                                          if(sideline<(screenwidth-CGALINE)){
  501.                                          sideline++;
  502.                                          cload();
  503.                                          }
  504.                                          break;
  505.  
  506.                                 default : break;
  507.                                 }
  508.                             }
  509.                         }
  510.                     }
  511.  
  512.        FREE_BUFF();
  513.        setcrtmode(TEXT);
  514.        printf("Cya on the \"Programmer's Forum..\"\n");
  515.        exit(0);
  516.  
  517. }
  518.  
  519.  
  520.  
  521.  
  522.  
  523.